home *** CD-ROM | disk | FTP | other *** search
/ Creative Computers / Creative Computers CD-ROM, Volume 1 (Legendary Design Technologies, Inc.)(1994).iso / shareware / intuition / yak_1.57 / source / handler.c < prev    next >
C/C++ Source or Header  |  1994-11-17  |  14KB  |  566 lines

  1. /*
  2.  * handler.c
  3.  *
  4.  * Routines to set up handler.
  5.  * Part of Yak.
  6.  *
  7.  * Martin W. Scott, 9/92.
  8.  */
  9. #include <exec/types.h>
  10. #include <exec/exec.h>
  11. #include <hardware/custom.h>
  12. #include <hardware/dmabits.h>
  13. #include <devices/console.h>
  14. #include <devices/input.h>
  15. #include <devices/inputevent.h>
  16. #include <libraries/commodities.h>
  17. #include <graphics/gfxbase.h>
  18. #include <graphics/gfxmacros.h>
  19. #include <graphics/displayinfo.h>
  20. #include <intuition/intuition.h>
  21. #include <intuition/intuitionbase.h>
  22. #include <proto/exec.h>
  23. #include <proto/dos.h>
  24. #include <proto/layers.h>
  25. #include <proto/graphics.h>
  26. #include <proto/intuition.h>
  27. #include <proto/commodities.h>
  28. #include <string.h>
  29.  
  30. #include "yak.h"
  31. #include "beep.h"
  32.  
  33.  
  34. static void __inline TurnMouseOn (void);
  35. static void __inline TurnMouseOff (void);
  36. static void __regargs IntuiOp (void (*routine) (APTR), APTR parameter);
  37. static void __regargs PopToFront (struct Window *win);
  38. static struct Window *WindowUnderMouse (void);
  39. static BOOL __regargs StrGadgetActive (struct Window *w);
  40.  
  41. extern struct Custom __far custom;
  42.  
  43. #define REBLANKCOUNT    10    /* how long to wait to reblank mouse */
  44.  
  45. void (*intui_routine) (APTR);    /* for intui_op's */
  46. APTR intui_parameter;
  47. CxObj *clickobj;
  48. ULONG clicksigflag, intuiopsigflag;
  49. static BYTE clicksigbit, intuiopsigbit = -1;
  50. static struct Task *thistask;
  51. static BOOL misspop;
  52.  
  53.  
  54. /* for screen click-to-back */
  55. void __stdargs
  56. MyScreenToBack (struct Screen *scr)
  57. {
  58.   struct Screen *ns = scr->NextScreen;
  59.   struct Window *win;
  60.  
  61.   if (!ns)
  62.       ns = IntuitionBase->FirstScreen;
  63.  
  64.   if (ns != scr)
  65.   {
  66.       ScreenToBack (scr);
  67.       if (scractivate && ns)
  68.       {
  69.           win = WindowUnderMouse();
  70.           if (win)
  71.               ActivateWindow (win);
  72.           else 
  73.               if (ns->FirstWindow)
  74.                   ActivateWindow (ns->FirstWindow);
  75.       }
  76.   }
  77. }
  78.  
  79.  
  80. /* Stub for Intuition routines - passes request on to main task.
  81.  * DO NOT CALL WHILE FORBID()ING!
  82.  
  83.  * Thanks to Eddy Carroll for this.
  84.  */
  85.  
  86. #define WTB(win)    IntuiOp(WindowToBack, win)
  87. #define WTF(win)    IntuiOp(WindowToFront, win)
  88. #define WACT(win)    IntuiOp((void (*)(APTR))ActivateWindow, win)
  89. #define STB(scr)    IntuiOp(MyScreenToBack, scr)
  90. #define STF(scr)    IntuiOp(ScreenToFront, scr)
  91.  
  92. static void __regargs
  93. IntuiOp (void (*routine) (APTR), APTR parameter)
  94. {
  95.   BYTE oldpri = SetTaskPri (thistask, 21);
  96.  
  97.   intui_routine = routine;
  98.   intui_parameter = parameter;
  99.   Signal (thistask, intuiopsigflag);
  100.   SetTaskPri (thistask, oldpri);
  101. }
  102.  
  103. /* pattern-matching on screen/window titles */
  104. #define IsXXXScreen(scr, pat)    (scr && (!scr->Title || MatchPattern(pat, scr->Title)))
  105. #define IsClickScreen(scr)    IsXXXScreen(scr, clickscrpat)
  106. #define IsAutoScreen(scr)    IsXXXScreen(scr, autoscrpat)
  107. #define IsXXXWindow(win, pat)    (!win->Title || MatchPattern(pat, win->Title))
  108. #define IsPopWindow(win)    IsXXXWindow(win,popwinpat)
  109. #define IsClickWindow(win)    IsXXXWindow(win,clickwinpat)
  110.  
  111. #define INTERRUPT void __interrupt __saveds
  112.  
  113. /* when is a window safe to bring to front and not already at front? */
  114. #define OkayToPop(win)    (!win->ReqCount && !(win->Flags & (WFLG_MENUSTATE|WFLG_BACKDROP)) \
  115.              && win->WLayer->ClipRect && win->WLayer->ClipRect->Next)
  116.  
  117.  
  118. /* WindowToFront only if no requester, not backdrop, not already front... */
  119. static void __regargs
  120. PopToFront (struct Window *win)
  121. {
  122.   /* want to avoid popping immediately after mousebutton/keyboard */
  123.   if (misspop)
  124.     misspop = FALSE;
  125.   else if (OkayToPop (win))
  126.     {
  127.       /* Does it pass pattern? */
  128.       if (IsPopWindow (win))
  129.           WTF (win);
  130.     }
  131. }
  132.  
  133. /* modified from DMouse */
  134. /* expects multitasking to be Forbid()en */
  135.  
  136. static struct Screen *mousescr;    /* the screen under the mouse */
  137.  
  138.  
  139. void
  140. ScreenUnderMouse( void )
  141. {
  142.   for (mousescr = IntuitionBase->FirstScreen ; 
  143.        mousescr && mousescr->TopEdge > 0 && mousescr->MouseY < 0; 
  144.        mousescr = mousescr->NextScreen);
  145. }
  146.  
  147.  
  148. static struct Window *
  149. WindowUnderMouse ( void )
  150. {
  151.   struct Layer *layer = NULL;
  152.  
  153.   for (mousescr = IntuitionBase->FirstScreen ; 
  154.        mousescr && mousescr->TopEdge > 0 && mousescr->MouseY < 0; 
  155.        mousescr = mousescr->NextScreen);
  156.   
  157.   if (mousescr)
  158.       layer = WhichLayer(&mousescr->LayerInfo, mousescr->MouseX, mousescr->MouseY);
  159.  
  160.   return (layer ? (struct Window *) layer->Window : NULL);
  161. }
  162.  
  163.  
  164. /* does active window have an active string gadget? */
  165. static BOOL __regargs
  166. StrGadgetActive (struct Window *w)
  167. {
  168.   struct Gadget *g = w->FirstGadget;
  169.  
  170.   for (; g; g = g->NextGadget)
  171.     if ((g->GadgetType & STRGADGET) && (g->Flags & GFLG_SELECTED))
  172.       return TRUE;
  173.   return FALSE;
  174. }
  175.  
  176. /* activate window under mouse */
  177. /* context sensitive; why tells routine how to behave */
  178. /* can be AUTO, KEY, SCREEN, RMBACT */
  179. #define AW    IntuitionBase->ActiveWindow
  180. #define AWS    IntuitionBase->ActiveWindow->WScreen
  181. #define FS    IntuitionBase->FirstScreen
  182. #define FSW    IntuitionBase->FirstScreen->FirstWindow
  183. void __regargs
  184. ActivateMouseWindow (BYTE why)
  185. {
  186.   struct Window *win;
  187.   BOOL forbidden = TRUE;
  188.  
  189.   Forbid ();
  190.  
  191.   if (win = WindowUnderMouse ())    /* window exists to activate */
  192.   {
  193.       /* either window is not active or auto-activating - need to pop? */
  194.       
  195.       if (win->Flags & WFLG_WINDOWACTIVE)    /* already active - needs popped? */
  196.       {
  197.           if (why == AUTO && autopop && IsAutoScreen (win->WScreen))
  198.           {
  199.               Permit (), forbidden = FALSE;
  200.               PopToFront (win);
  201.           }
  202.       }
  203.       else if (why != AUTO || IsAutoScreen (win->WScreen))
  204.       {
  205.           /* window is not active, should we try to activate it? */
  206.           
  207.           /* AW is IntuitionBase->ActiveWindow */
  208.           if (!AW ||
  209.               !(AW->Flags & WFLG_MENUSTATE) &&    /* not showing menus */
  210.               !(why == KEY && StrGadgetActive (AW)))    /* no str gad active */
  211.           {
  212.               /* finally... */
  213.               Permit (), forbidden = FALSE;
  214.               
  215.               /* do autopop? */
  216.               if (why == AUTO && autopop)
  217.                   PopToFront (win);
  218.               
  219.               if (why == KEY)
  220.                   ActivateWindow (win);    /* need this to avoid losing keys */
  221.               else
  222.                   WACT (win);    /* ...activate window */
  223.           }
  224.       }
  225.   }
  226.   else
  227.     /* no window under mouse... */
  228.     {
  229.       if (mousescr && mousescr->FirstWindow &&
  230.       ((why == SCREEN) || (why == RMBACT && AW && AWS != mousescr)))
  231.     {
  232.       Permit (), forbidden = FALSE;
  233.       WACT (mousescr->FirstWindow);        /* ...activate window */
  234.     }
  235.     }
  236.   if (forbidden)
  237.     Permit ();
  238. }
  239.  
  240. static UWORD __chip posctldata[4];
  241. static struct SimpleSprite simplesprite =
  242. {posctldata, 0, 0, 0, 0};
  243. static BOOL mouseoff;        /* is mouse off? (MB_SPRITES only) */
  244.  
  245. static void __inline
  246. TurnMouseOn ()            /* restore mouse-pointer */
  247. {
  248.   if (mouseblank == MB_SPRITES)    /* really dirty blanking */
  249.     {                /* but guaranteed to work... */
  250.       if (mouseoff)
  251.     {
  252.       Forbid ();
  253.       WaitTOF ();
  254.       ON_SPRITE;
  255.       Permit ();
  256.     }
  257.     }
  258.   /* else using FreeSprite solution - unblanks when needed */
  259.   mouseoff = FALSE;
  260. }
  261.  
  262. static void __inline
  263. TurnMouseOff ()            /* blank mouse-pointer */
  264. {
  265.   if (!mouseoff)        /* no point in turning it off twice... */
  266.     {
  267.       Forbid ();
  268.  
  269.       if (mouseblank == MB_SPRITES)
  270.     {
  271.       WaitTOF ();
  272.       OFF_SPRITE;
  273.       custom.spr[0].dataa = custom.spr[0].datab = 0;
  274.     }
  275.       else
  276.     {
  277.       FreeSprite (0);
  278.       GetSprite (&simplesprite, 0);
  279.     }
  280.  
  281.       Permit ();
  282.  
  283.       mouseoff = TRUE;
  284.     }
  285. }
  286.  
  287. static BOOL blanked;
  288. static struct Screen *blankscr;
  289.  
  290. /* blank display, by putting up a black screen */
  291. /* this screen's displaymode is cloned from front screen */
  292. void
  293. BlankScreen ()
  294. {
  295.     ULONG modeid = INVALID_ID;
  296.     
  297.     if (blankscr)
  298.         ScreenToFront (blankscr);
  299.     else
  300.     {
  301.         Forbid ();
  302.         if (FS)
  303.             modeid = GetVPModeID (&(FS->ViewPort));
  304.         Permit ();
  305.         if (modeid == INVALID_ID)
  306.             modeid = LORES_KEY;
  307.         
  308.         if (blankscr = OpenScreenTags (NULL, SA_Depth, 1,
  309.                                        SA_Quiet, TRUE,
  310.                                        SA_Behind, TRUE,
  311.                                        SA_DisplayID, modeid,
  312.                                        TAG_DONE))
  313.         {
  314.             SetRGB4 (&blankscr->ViewPort, 0, 0, 0, 0);
  315.             ScreenToFront (blankscr);
  316.             blanked = TRUE;
  317.         }
  318.     }
  319.     OFF_SPRITE;
  320.     custom.spr[0].dataa = custom.spr[0].datab = 0;
  321. }
  322.  
  323. /* unblank display, i.e. close our screen */
  324. void
  325. UnBlankScreen ()
  326. {
  327.   if (blankscr)
  328.       CloseScreen (blankscr);
  329.   blankscr = NULL;
  330.   blanked = FALSE;
  331.   ON_SPRITE;
  332. }
  333.  
  334. #define ALL_BUTTONS    (IEQUALIFIER_LEFTBUTTON|IEQUALIFIER_RBUTTON|IEQUALIFIER_MIDBUTTON)
  335. #define KEY_QUAL    (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT \
  336.             |IEQUALIFIER_CONTROL \
  337.             |IEQU